package com.cskaoyan.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;

import javax.sql.DataSource;
import java.io.IOException;

/**
 * @author stone
 * @date 2022/08/30 15:07
 */
@Configuration
@ComponentScan("com.cskaoyan")
public class SpringConfiguration {

    // SqlSessionFactory
    /*@Bean
    public SqlSessionFactory sqlSessionFactory() throws IOException {
        // 这样子写MyBatis的配置只能通过配置文件来提供
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis.xml"));
        return sessionFactory;
    }*/

    // 我们开发过程中期望的是通过Java代码来配置 → 打补丁 拓展包 → mybatis-spring
    // 提供一个能够获得SqlSessionFactory的新的方式，并且可以通过Java代码完成对应的配置
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        // DataSource是必须要配置的
        sqlSessionFactoryBean.setDataSource(dataSource);
        return sqlSessionFactoryBean;
    }

    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/cskaoyan_db?useUnicode=true&characterEncoding=utf-8");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        //return dataSource();
        return dataSource;
    }

    // Mapper组件 → 通过MapperScannerConfigurer
    // 注册这个组件，这个组件在注册的过程中会帮我们帮 Mapper组件注册了
    // 需要我们来提供信息：1、mapper的包目录；2、SqlSessionFactory
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        // 扫描范围是这个包以及它的所有子包
        // 如果写com.cskaoyan会扫描到除了Mapper接口之外的其他接口，这些接口没有与之对应的映射文件 → 无效绑定异常
        mapperScannerConfigurer.setBasePackage("com.cskaoyan.mapper");
        // 提供id能否获得该id对应的组件呢？可以获得、applicationContext和id都有了
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
        return mapperScannerConfigurer;
    }

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }

    @Bean
    public TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
        TransactionTemplate transactionTemplate = new TransactionTemplate();
        transactionTemplate.setTransactionManager(transactionManager);
        return transactionTemplate;
    }
}
